#!/bin/bash
#
# Packs the Pulley subscription control file. Computes and automatically
# includes the security signature for the payload file.
#
# Author:   Dr. Mike Murphy (mmurphy2@coastal.edu)
# Revision: 18 November 2013
#
#   Copyright 2012-2013 Coastal Carolina University
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
#


## p_cmd_pack_help
##
## Echoes help information for the pack command. Returns 0.
##
function p_cmd_pack_help() {
	cat << EOF
Usage: pulley pack <packing file>

TODO: Update for new security model

Computes the GPG signature of the subscription payload and produces a
Pulley subscription control file containing the signature. In order for
the subscription to work properly, the control file must contain the
URL of the payload file. It is also desirable for the control file
to specify the URL of the public GPG key used to sign the payload.

In order to manage this process, it is necessary to specify a packing file,
which describes the configuration information that should be placed into
the generated control file. This packing file MUST contain the following
directives in name=value format:

PAYLOAD_URL=<url>
  Specifies the final URL of the payload file. This is the URL that the
  client will use to download the payload (in order words, the URL of the
  location to which the payload will be uploaded to be transmitted by the
  server). If the clients will retrieve the payload via a mounted
  filesystem (e.g. via NFS), this should be the full path to the payload,
  as seen on the client machine(s).

INPUT_PAYLOAD=<path>
  Specifies the filename of the prepared payload file. This file needs to
  be ready for use by the clients before packing the control file, since
  the packed control file will contain a GPG signature of the payload file.
  It is recommended that this file have a .payload extension.

OUTPUT_FILE=<path>
  Specifies the filename to which the control file will be written. It is
  suggested that this filename have a .pulley extension.


The following OPTIONAL directives may also be added to the packing file:

PUB_KEY=<url>
  Specifies the URL (or path, in the case that all clients mount a common
  filesystem such as NFS), as seen by the client, of a copy of the public
  GPG key used to sign the payload.

DEFAULT_KEY=<key>
  Selects the GPG key to use. See the documentation for gpg(1) for details.
    
LOCAL_USER=<local-user>
  Another method for selecting the GPG key to use. See the documentation
  for gpg(1) for details.


ADVANCED: The packing file is simply a Bash script that is sourced by the
Pulley pack command processor. Provisions have been included to define a
Bash function named p_cmd_pack_post that will perform post-processing
steps in the packing operation, such as uploading the subscription files
to a remote server for hosting. The following example uses SCP to upload
the subscription and signature files to a directory named /srv/http/pulley
on remote host darkstar:

function p_cmd_pack_post() {
	scp "${INPUT_PAYLOAD}" "${OUTPUT_FILE}" darkstar:/srv/http/pulley
}
EOF
	return 0
}


## p_cmd_pack_summary
##
## Echoes summary information for the pack command. Returns 0.
##
function p_cmd_pack_summary() {
	echo "Packs the Pulley control file for a given payload"
	return 0
}


## p_cmd_pack_write_header
##
## Writes the control file header to the OUTPUT_FILE specified in the
## packing file, sourced elsewhere. Returns 0 on success, non-zero otherwise.
##
function p_cmd_pack_write_header() {
	local status=0
	echo "PAYLOAD_URL=${PAYLOAD_URL}" > "${OUTPUT_FILE}"
	status=$?
	[ -n "${PUB_KEY}" ] && echo "PUB_KEY=${PUB_KEY}" >> "${OUTPUT_FILE}"
	return ${status}
}


## p_cmd_append_signature
##
## Generates and appends the GPG signature to the OUTPUT_FILE sourced
## elsewhere. Returns 0 on success, non-zero on failure.
##
function p_cmd_pack_append_signature() {
	local -a gpgopts
	local status=0
	sed -i '/^$/d' "${OUTPUT_FILE}"
	echo "__SIGNATURE_FOLLOWS__" >> "${OUTPUT_FILE}"
	local sigout=$(s_mktempfile)
	
	# GPG options
	[ -n "${DEFAULT_KEY}" ] && gpgopts+=("--default-key" "${DEFAULT_KEY}")
	[ -n "${LOCAL_USER}" ] && gpgopts+=("--local-user" "${LOCAL_USER}")
	
# TODO: update
	psec_gpg_sign subscription "${sigout}" "${INPUT_PAYLOAD}" "${gpgopts[@]}"
	status=$?
	cat "${sigout}" >> "${OUTPUT_FILE}"
	return ${status}
}


## p_cmd_pack_validate
##
## Validates the newly created Pulley control file. Currently unimplemented
## and always returns 0.
##
function p_cmd_pack_validate() {
	return 0
}


## p_cmd_pack_post
##
## Dummy function that does nothing. This function can be overridden in the
## packing file to perform some step, such as uploading the payload and
## control files to a remote server. Otherwise, this version of the
## function will be called, which does nothing and returns 0.
##
function p_cmd_pack_post() {
	return 0
}


## p_cmd_pack <packing file>
##
## Sources the <packing file> and performs the control file packing
## operation, implementing the pack command. Returns 0 on success,
## non-zero if an error occurs.
##
function p_cmd_pack() {
	. "$1"
	local status=$?
	if [[ ${status} -eq 0 ]]; then
		p_cmd_pack_write_header
		status=$?
		if [[ ${status} -eq 0 ]]; then
			p_cmd_pack_append_signature
			status=$?
			if [[ ${status} -eq 0 ]]; then
				p_cmd_pack_validate
				status=$?
				if [[ ${status} -eq 0 ]]; then
					p_cmd_pack_post
					status=$?
				fi
			fi
		fi
	fi
	return ${status}
}
